#pragma once

class IThread
{
public:
	virtual void OnThreadStart(void){}
	virtual void OnThreadExit(void){}
	virtual BOOL OnThreadTask(LPARAM lParam)=0;
};

class CThread
{
public:
	CThread()
	{
		m_hThread = NULL;
		m_pEntity = NULL;
	}

	BOOL Start(IThread *pEntity, LPARAM lParam)
	{
		DWORD pid;
		if(m_hThread != NULL)
		{
			return FALSE;
		}
		m_lParam  = lParam;
		m_pEntity = pEntity;
		m_hThread = CreateThread(NULL, 0, StaticThreadProcessor, this, 0, &pid);
		return m_hThread != NULL;
	}

	void Stop(void)
	{
		if(m_hThread != NULL)
		{
			TerminateThread(m_hThread, 0);
			CloseHandle(m_hThread);
			m_pEntity->OnThreadExit();
		}
		m_hThread = NULL;
	}

	BOOL IsStarted()
	{
		return m_hThread != NULL;
	}

private:
	void DynamicThreadProcessor()
	{
		BOOL bRet = TRUE;
		m_pEntity->OnThreadStart();
		while(bRet)
		{
			bRet = m_pEntity->OnThreadTask(m_lParam);
		}
		m_pEntity->OnThreadExit();
		CloseHandle(m_hThread);
		m_hThread = NULL;
	}

	static DWORD WINAPI StaticThreadProcessor(LPVOID data)
	{
		CThread *self;
		self = (CThread *)data;
		self->DynamicThreadProcessor();
		return 0;
	}

private:
	HANDLE m_hThread;
	LPARAM m_lParam;
	IThread *m_pEntity;
};
